package com.zs.grain.service

import android.content.Context
import com.google.gson.JsonObject
import com.xnkj1688.semplibrary.entity.*
import com.xnkj1688.semplibrary.signalr.SignalRBase
import com.xnkj1688.semplibrary.ulti.*
import io.reactivex.Single
import io.reactivex.subjects.SingleSubject

import java.util.Date

import javax.inject.Inject
import javax.inject.Singleton

/**
 * Created by Wesley on 2017/7/15.
 */

@Singleton
class SignalRService @Inject constructor(override val mContext: Context) : SignalRBase(mContext) {

    @Inject
    lateinit var mSignalRHub: SignalRHub

    @Synchronized
    override fun init(url: String, deviceId: String, verifyCode: String) {
        mSignalRHub.mSignalRService = this
        super.init(url, deviceId, verifyCode)
        super.start(mSignalRHub)
    }

    override fun init(url: String) {
        super.init(url)
        super.start(mSignalRHub)
    }

    val sceneQr: Single<String>
        get() = super.invoke(String::class.java, "GetSceneQr")

    val settings: Single<Array<Setting>>
        get() = super.invoke(Array<Setting>::class.java, "GetSettings")

    val goods: Single<Array<Good>>
        get() = super.invoke(Array<Good>::class.java, "GetGoods")

    val components: Single<Array<Component>>
        get() = super.invoke(Array<Component>::class.java, "GetComponents")

    val adjustments: Single<Array<Adjustment>>
        get() = super.invoke(Array<Adjustment>::class.java, "GetAdjustments")

    val ingridents: Single<Array<Ingrident>>
        get() = super.invoke(Array<Ingrident>::class.java, "GetIngridents")

    val receipes: Single<Array<Receipe>>
        get() = super.invoke(Array<Receipe>::class.java, "GetReceipes")

    val categories: Single<Array<Category>>
        get() = super.invoke(Array<Category>::class.java, "GetCategories")

    val images: Single<Array<Image>>
        get() = super.invoke(Array<Image>::class.java, "GetImages")

    val menus: Single<Array<Menu>>
        get() = super.invoke(Array<Menu>::class.java, "GetMenus")

    val tracks: Single<Array<Track>>
        get() = super.invoke(Array<Track>::class.java, "GetTracks")

    val advertisements: Single<Array<Advertisement>>
        get() = super.invoke(Array<Advertisement>::class.java, "GetAdvertisements")

    fun getImage(imageId: Long): Single<String> {
        return super.invoke(String::class.java, "GetImage", imageId)
    }

    //    fun getResource(id: Long): Single<Resource> {
//        return super.invoke(Resource::class.java, "GetResource", id)
//    }
    fun checkUpdate(type: String, version: String): Single<Pair<Int, String>> {
        val result = SingleSubject.create<Pair<Int, String>>()
        super.invoke(JsonObject::class.java, "checkUpdate", type, version)
            .subscribe({
                if (it.has("Id") && it.has("FileName")) {
                    result.onSuccess(Pair(it.get("Id").asInt, it.get("FileName").asString))
                } else {
                    result.onSuccess(Pair(0, ""))
                }
            }, {
                result.onError(it)
            })
        return result
    }

    fun downloadResource(id: Long): Single<String> {
        return super.invoke(String::class.java, "DownloadResource", id)
    }

    fun getTrack(counterNo: Int, no: Int): Single<Track> {
        return super.invoke(Track::class.java, "GetTrack", counterNo, no)
    }

    fun getPaymentQr(order: Order): Single<JsonObject> {
        return super.invoke(JsonObject::class.java, "GetPaymentQr", order, Date())
    }

    fun checkPayment(orderId: Long): Single<Int> {
        return super.invoke(Int::class.java, "CheckPayment", orderId)
    }

    fun checkPayment2(orderId: Long, payWay: Int): Single<Int> {
        return super.invoke(Int::class.java, "CheckPayment2", orderId, payWay)
    }

    fun closePayment(orderId: Long): Single<Int> {
        return super.invoke(Int::class.java, "CheckPayment", orderId)
    }

    fun takeOrder(orderId: Long): Single<Order> {
        return super.invoke(Order::class.java, "TakeOrder", orderId)
    }

    fun uploadDeviceState(state: String, data: String): Single<Boolean> {
        return super.invoke(Boolean::class.java, "uploadDeviceState", state, data, Date())
    }

    fun uploadOrder(order: Order): Single<Boolean> {
        return super.invoke(Boolean::class.java, "UploadOrder", order, Date())
    }

    fun uploadSystemLogs(logs: List<SystemLog>): Single<Boolean> {
        return super.invoke(Boolean::class.java, "UploadSystemLogs", logs, Date())
    }

    fun uploadComponents(components: List<Component>): Single<Boolean> {
        return super.invoke(Boolean::class.java, "UploadComponents", components)
    }

    fun uploadAdjustments(adjustments: List<Adjustment>): Single<Boolean> {
        return super.invoke(Boolean::class.java, "UploadAdjustments", adjustments)
    }

    fun uploadAdjustment(adjustment: Adjustment): Single<Boolean> {
        return super.invoke(Boolean::class.java, "UploadAdjustment", adjustment)
    }

    fun uploadTracks(tracks: List<Track>): Single<Boolean> {
        return super.invoke(Boolean::class.java, "UploadTracks", tracks)
    }

    fun uploadSnapshots(snapshots: List<Snapshot>): Single<Boolean> {
        return super.invoke(Boolean::class.java, "UploadSnapshots", snapshots, Date())
    }

    fun uploadCash(cash: Cash): Single<Boolean> {
        return super.invoke(Boolean::class.java, "SaveCash", cash, Date())
    }

    fun uploadCashLogs(logs: List<CashLog>): Single<Boolean> {
        return super.invoke(Boolean::class.java, "UploadCash", logs, Date())
    }

    fun uploadAdvertisements(ads: Array<Advertisement>): Single<Boolean> {
        return super.invoke(Boolean::class.java, "UploadAdvertisements", ads)
    }

    fun uploadMachineInfo(appInfo: MachineInfo): Single<Boolean> {
        return super.invoke(Boolean::class.java, "UploadMachineInfo", appInfo)
    }

    fun payByFace(order: Order, customerId: String, faceinfo: String): Single<JsonObject> {
        return super.invoke(
            JsonObject::class.java,
            "PayByFace",
            order,
            customerId,
            faceinfo,
            Date()
        )
    }

    fun payByFaceForYc(order: Order, faceinfo: String): Single<JsonObject> {
        return super.invoke(JsonObject::class.java, "PayByFaceForYc", order, faceinfo, Date())
    }

    fun payByFaceForIcbc(
        order: Order,
        customerId: String,
        faceinfo: String
    ): Single<JsonObject> {
        return super.invoke(
            JsonObject::class.java,
            "PayByFaceForIcbc",
            order,
            customerId,
            faceinfo,
            Date()
        )
    }

    fun payByFaceForCcb(
        order: Order,
        telPhonelast4Str: String,
        faceinfo: String
    ): Single<JsonObject> {
        return super.invoke(
            JsonObject::class.java,
            "PayByFaceForCcb",
            order,
            telPhonelast4Str,
            faceinfo,
            Date()
        )
    }

    fun register(telPhoneStr: String, faceinfo: String): Single<Boolean> {
        return super.invoke(
            Boolean::class.java,
            "RegisterForCcbFace",
            telPhoneStr,
            faceinfo,
            Date()
        )
    }

    fun unregister(telPhoneStr: String, faceinfo: String): Single<Boolean> {
        return super.invoke(
            Boolean::class.java,
            "UnregisterForCcbFace",
            telPhoneStr,
            faceinfo,
            Date()
        )
    }

    companion object {
        val TAG = "SignalRService"
    }
}
